#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QTcpSocket>
#include <QObject>
#include <QHostAddress>
#include <QtEndian>
#include <QJsonDocument>
#include <QJsonObject>
#include <QCryptographicHash>
#include <QMutex>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <QDataStream>
#include "VideoStructs.h"
// 消息类型枚举
enum TaskType {
    // 登录相关类型（1-6）
    TASK_TYPE_LOGIN_SECTION1 = 1,
    TASK_TYPE_LOGIN_SECTION1_RESP_OK = 2,
    TASK_TYPE_LOGIN_SECTION1_RESP_ERROR = 3,
    TASK_TYPE_LOGIN_SECTION2 = 4,
    TASK_TYPE_LOGIN_SECTION2_RESP_OK = 5,
    TASK_TYPE_LOGIN_SECTION2_RESP_ERROR = 6,

    // 注册相关类型（7-12）
    TASK_TYPE_REGISTER_SECTION1 = 7,          // 注册第一步：发送用户名
    TASK_TYPE_REGISTER_SECTION1_RESP_OK = 8,  // 注册第一步响应：成功（带Salt）
    TASK_TYPE_REGISTER_SECTION1_RESP_ERROR = 9, // 注册第一步响应：失败
    TASK_TYPE_REGISTER_SECTION2 = 10,         // 注册第二步：发送加密密码
    TASK_TYPE_REGISTER_SECTION2_RESP_OK = 11, // 注册第二步响应：成功
    TASK_TYPE_REGISTER_SECTION2_RESP_ERROR = 12, // 注册第二步响应：失败

    // 设备管理相关类型
    TASK_TYPE_DEVICE_LIST_REQUEST = 20,
    TASK_TYPE_DEVICE_LIST_RESPONSE = 21,
    TASK_TYPE_DEVICE_ADD_REQUEST = 22,
    TASK_TYPE_DEVICE_ADD_RESPONSE = 23,
    TASK_TYPE_DEVICE_REMOVE_REQUEST = 24,
    TASK_TYPE_DEVICE_REMOVE_RESPONSE = 25,
    TASK_TYPE_DEVICE_UPDATE_REQUEST = 26,
    TASK_TYPE_DEVICE_UPDATE_RESPONSE = 27,

    // 视频流相关类型
    TASK_TYPE_STREAM_START_REQUEST = 30,
    TASK_TYPE_STREAM_START_RESPONSE = 31,
    TASK_TYPE_STREAM_STOP_REQUEST = 32,
    TASK_TYPE_STREAM_STOP_RESPONSE = 33,
    TASK_TYPE_STREAM_METADATA = 34,   // 发送视频元数据
    TASK_TYPE_STREAM_DATA = 35,        // 发送视频数据

    // 录像管理相关类型
    TASK_TYPE_RECORD_QUERY_REQUEST = 40,
    TASK_TYPE_RECORD_QUERY_RESPONSE = 41,
    TASK_TYPE_RECORD_PLAY_REQUEST = 42,
    TASK_TYPE_RECORD_PLAY_RESPONSE = 43,

    // PTZ控制相关类型
    TASK_TYPE_PTZ_CONTROL_REQUEST = 44,
    TASK_TYPE_PTZ_CONTROL_RESPONSE = 45,
};

// 分片头结构体
//#pragma pack(push, 1)
//struct FragmentHeader {
//    uint32_t packetId;        // 数据包ID
//    uint16_t totalFragments;  // 总分片数
//    uint16_t currentFragment; // 当前分片序号
//    uint16_t dataLength;      // 数据长度
//    uint8_t isFragmented;     // 是否分片 (0-否, 1-是)
//};
//#pragma pack(pop)

class tcpclient : public QObject {
    Q_OBJECT
public:
    explicit tcpclient(QObject *parent = nullptr);
    // 连接服务器
    bool connectToServer(const QString &ip, quint16 port);
    // 注册第一步：发送用户名
    void sendRegisterStep1(const QString &username);
    // 注册第二步：发送加密后的密码
    void sendRegisterStep2(const QString &encryptedPassword);
    // 登录第一步：发送用户名（与服务器流程匹配）
    void sendLoginStep1(const QString &username);
    // 登录第二步：发送加密密码
    void sendLoginStep2(const QString &encryptedPassword);
    // 生成带Salt的MD5（格式：$1$salt$ + 22位哈希）
    QString generateMd5WithSalt(const QString &password, const QString &salt);
    // 发送视频流请求
    void sendStreamRequest(int cameraId, bool isMainStream);
    // 发送云台控制请求
    void sendPTZControlRequest(int cameraId, const QString &command, int duration = 1000);

    bool isConnected() const;
    bool isConnecting() const;

signals:
    // 注册第一步结果（成功时带Salt）
    void registerStep1Result(bool success, const QString &msg, const QString &salt = "");
    // 注册第二步结果
    void registerStep2Result(bool success, const QString &msg);
    // 登录第一步结果（带Salt）
    void loginStep1Result(bool success, const QString &msg, const QString &salt = "");
    // 登录第二步结果
    void loginStep2Result(bool success, const QString &msg);
    // 连接/通信错误
    void connectError(const QString &msg);
    void disconnected();
    // 新增视频流响应信号
    void streamUrlReceived(int channel, bool isMainStream, const QString &url);
    // 新增云台控制响应信号
    void ptzControlResult(bool success, const QString &msg);
    void metadataReceived(const VideoMetadata& metadata);
    void videoFrameReceived(const VideoFrame& frame);

private slots:
    void onReadyRead();
    void onError(QAbstractSocket::SocketError err);

private:
    // 解析注册第一步响应
    void parseRegisterStep1Response(const QByteArray &data);
    // 解析注册第二步响应
    void parseRegisterStep2Response(const QByteArray &data);
    // 解析登录第一步响应
    void parseLoginStep1Response(const QByteArray &data);
    // 解析登录第二步响应
    void parseLoginStep2Response(const QByteArray &data);
    // 解析视频流响应
    void parseStreamResponse(const QByteArray &data);
    // 解析云台控制响应
    void parsePTZControlResponse(const QByteArray &data);

private:

    // 当前请求的视频通道号
    int m_currentRequestChannel;
    
    struct FragmentBuffer {
            QByteArray data;
            uint32_t packetId;
            uint16_t receivedFragments;
            uint16_t totalFragments;
        };

//        QMap<uint32_t, FragmentBuffer> m_fragmentBuffers; // 分片缓冲区
//        QMutex m_fragmentMutex; // 线程安全锁

    QTcpSocket m_socket;
    QString m_registerUsername; // 临时保存注册的用户名
    QString m_loginUsername;    // 临时保存登录的用户名
    QString m_tempRegisterPassword;

    QByteArray m_readBuffer; // 读取缓冲区
};



#endif // TCPCLIENT_H
